package org.example.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Random;

// 这是切面类，里面有增强的方法
@Component
@Aspect
public class MyAspect {
    @Pointcut("execution( * org.example.service.*.add(..))")
    public void a(){}
    @Pointcut("execution( * org.example.service.*.delete(..))")
    public void b(){}
    @Pointcut("execution( * org.example.service.*.find*(..))")
    public void c(){}

    // 定义一个通用切入点，包含所有需要统计时间的方法
    @Pointcut("a() || b() || c()")
    public void time统计(){}


    @Before("a()|| b()|| c()")
    public void log(){
        System.out.println("============================");
        System.out.println("hi，我是一个前置增强");
        System.out.println("日志增强");
        System.out.println(new Date());
        System.out.println("============================");

    }

    @Before("a()|| b()|| c()")
    public void checkRight(){
        System.out.println("============================");
        System.out.println("权限校验增强");
        Random r = new Random();
        if ( r.nextInt(2)==1){
            System.out.println("校验失败");
            throw new RuntimeException("用户权限不足");
        }else{
            System.out.println("校验成功");
        }
        System.out.println("============================");
    }

    @AfterReturning(value="a()",returning="id")
    public void recordReturnValue( int id ) {
        System.out.println("============================");
        System.out.println("添加成功，新产品的id为:" + id);
        System.out.println("bye,我是一个后置增强");
        System.out.println("============================");
    }

    // 新增环绕通知用于统计方法执行时间（毫秒级）
    @Around("time统计()")
    public Object calculateExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        // 记录开始时间（毫秒）
        long startTime = System.currentTimeMillis();

        try {
            // 执行目标方法
            return joinPoint.proceed();
        } finally {
            // 记录结束时间并计算差值
            long endTime = System.currentTimeMillis();
            long executionTime = endTime - startTime;

            // 输出执行时间信息
            System.out.println("============================");
            System.out.println("方法 " + joinPoint.getSignature().getName() +
                    " 执行时间: " + executionTime + " 毫秒");
            System.out.println("============================");
        }
    }
}
